﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing;
using System.Drawing.Design;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Windows.Forms;

namespace APP.HELPER.Utils.Localization
{
    [ToolboxItem(false)]
    public class CultureManager : Component
    {
        public delegate void CultureChangedHandler(CultureInfo newCulture);
        private const AnchorStyles anchorLeftRight = AnchorStyles.Left | AnchorStyles.Right;
        private const AnchorStyles anchorTopBottom = AnchorStyles.Top | AnchorStyles.Bottom;
        private const AnchorStyles anchorAll = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
        private static CultureInfo _applicationUICulture;
        private static bool _synchronizeThreadCulture = true;
        private Control _managedControl;
        private CultureInfo _uiCulture;
        private bool _preserveFormSize = true;
        private bool _preserveFormLocation = true;
        private List<string> _excludeProperties = new List<string>();
        private bool _synchronizeUICulture = true;
        public static event CultureManager.CultureChangedHandler ApplicationUICultureChanged;
        public event CultureManager.CultureChangedHandler UICultureChanged;
        public static CultureInfo ApplicationUICulture
        {
            get
            {
                if (CultureManager._applicationUICulture == null)
                {
                    CultureManager._applicationUICulture = Thread.CurrentThread.CurrentUICulture;
                }
                return CultureManager._applicationUICulture;
            }
            set
            {
                if (value == null)
                {
                    throw new ArgumentNullException();
                }
                if (!value.Equals(CultureManager._applicationUICulture))
                {
                    CultureManager._applicationUICulture = value;
                    CultureManager.SetThreadUICulture(CultureManager.SynchronizeThreadCulture);
                    if (CultureManager.ApplicationUICultureChanged != null)
                    {
                        CultureManager.ApplicationUICultureChanged(value);
                    }
                }
            }
        }
        public static bool SynchronizeThreadCulture
        {
            get
            {
                return CultureManager._synchronizeThreadCulture;
            }
            set
            {
                CultureManager._synchronizeThreadCulture = value;
                if (value)
                {
                    CultureManager.SetThreadUICulture(true);
                }
            }
        }
        [Description("The control or form to manage the UICulture for")]
        public Control ManagedControl
        {
            get
            {
                if (this._managedControl == null)
                {
                    if (this.Site != null)
                    {
                        IDesignerHost designerHost = this.Site.GetService(typeof(IDesignerHost)) as IDesignerHost;
                        if (designerHost != null && designerHost.Container != null && designerHost.Container.Components.Count > 0)
                        {
                            this._managedControl = (designerHost.Container.Components[0] as Control);
                        }
                    }
                }
                return this._managedControl;
            }
            set
            {
                this._managedControl = value;
            }
        }
        [DefaultValue(true), Description("Should the form size be preserved when the culture is changed")]
        public bool PreserveFormSize
        {
            get
            {
                return this._preserveFormSize;
            }
            set
            {
                this._preserveFormSize = value;
            }
        }
        [DefaultValue(true), Description("Should the form location be preserved when the culture is changed")]
        public bool PreserveFormLocation
        {
            get
            {
                return this._preserveFormLocation;
            }
            set
            {
                this._preserveFormLocation = value;
            }
        }
        [Description("List of properties to exclude when applying culture specific resources"), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Editor("System.Windows.Forms.Design.StringCollectionEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))]
        public List<string> ExcludeProperties
        {
            get
            {
                return this._excludeProperties;
            }
            set
            {
                if (value == null)
                {
                    throw new ArgumentNullException();
                }
                this._excludeProperties = value;
            }
        }
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public CultureInfo UICulture
        {
            get
            {
                if (this._uiCulture == null)
                {
                    this._uiCulture = CultureManager.ApplicationUICulture;
                }
                return this._uiCulture;
            }
            set
            {
                if (value == null)
                {
                    throw new ArgumentNullException();
                }
                this.ChangeUICulture(value);
            }
        }
        [DefaultValue(true), Description("Should the UICulture of this form be changed when the ApplicationUICulture")]
        public bool SynchronizeUICulture
        {
            get
            {
                return this._synchronizeUICulture;
            }
            set
            {
                this._synchronizeUICulture = value;
            }
        }
        public static void SetThreadUICulture(bool synchronizeThreadCulture)
        {
            Thread.CurrentThread.CurrentUICulture = CultureManager.ApplicationUICulture;
            if (synchronizeThreadCulture)
            {
                if (CultureManager.ApplicationUICulture.IsNeutralCulture)
                {
                    Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(CultureManager.ApplicationUICulture.Name);
                }
                else
                {
                    Thread.CurrentThread.CurrentCulture = CultureManager.ApplicationUICulture;
                }
            }
        }
        public CultureManager()
        {
            CultureManager.ApplicationUICultureChanged = (CultureManager.CultureChangedHandler)Delegate.Combine(CultureManager.ApplicationUICultureChanged, new CultureManager.CultureChangedHandler(this.OnApplicationUICultureChanged));
        }
        public CultureManager(IContainer container)
            : this()
        {
            container.Add(this);
        }
        private bool ShouldSerializeExcludeProperties()
        {
            return this._excludeProperties.Count > 0;
        }
        private void ResetExcludeProperties()
        {
            this._excludeProperties.Clear();
        }
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                CultureManager.ApplicationUICultureChanged = (CultureManager.CultureChangedHandler)Delegate.Remove(CultureManager.ApplicationUICultureChanged, new CultureManager.CultureChangedHandler(this.OnApplicationUICultureChanged));
            }
            base.Dispose(disposing);
        }
        protected virtual void OnApplicationUICultureChanged(CultureInfo newCulture)
        {
            if (this.SynchronizeUICulture)
            {
                this.ChangeUICulture(newCulture);
            }
        }
        protected virtual void OnUICultureChanged(CultureInfo newCulture)
        {
            if (this.UICultureChanged != null)
            {
                this.UICultureChanged(newCulture);
            }
        }
        protected virtual void ChangeUICulture(CultureInfo culture)
        {
            if (!culture.Equals(this._uiCulture))
            {
                this._uiCulture = culture;
                if (this._managedControl != null)
                {
                    this._managedControl.SuspendLayout();
                    foreach (Control control in this._managedControl.Controls)
                    {
                        control.SuspendLayout();
                    }
                    try
                    {
                        this.ApplyResources(this._managedControl.GetType(), this._managedControl, culture);
                        this.OnUICultureChanged(culture);
                    }
                    finally
                    {
                        foreach (Control control in this._managedControl.Controls)
                        {
                            control.ResumeLayout();
                        }
                        this._managedControl.ResumeLayout();
                    }
                }
            }
        }
        private static void SetThreadCulture(CultureInfo value)
        {
            if (value.IsNeutralCulture)
            {
                Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(value.Name);
            }
            else
            {
                Thread.CurrentThread.CurrentCulture = value;
            }
        }
        private void LoadResources(ComponentResourceManager rm, CultureInfo culture, SortedList<string, object> resources)
        {
            if (!culture.Equals(CultureInfo.InvariantCulture))
            {
                this.LoadResources(rm, culture.Parent, resources);
            }
            ResourceSet resourceSet = rm.GetResourceSet(culture, true, true);
            if (resourceSet != null)
            {
                foreach (DictionaryEntry dictionaryEntry in resourceSet)
                {
                    resources[(string)dictionaryEntry.Key] = dictionaryEntry.Value;
                }
            }
        }
        protected virtual void SetControlSize(Control control, Size size)
        {
            if (!(control is Form) || !this.PreserveFormSize)
            {
                if (control.Dock != DockStyle.Fill && control.Anchor != (AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right))
                {
                    if (control.Dock == DockStyle.Top || control.Dock == DockStyle.Bottom || (control.Anchor & (AnchorStyles.Left | AnchorStyles.Right)) == (AnchorStyles.Left | AnchorStyles.Right))
                    {
                        size.Width = control.Width;
                    }
                    if (control.Dock == DockStyle.Left || control.Dock == DockStyle.Right || (control.Anchor & (AnchorStyles.Top | AnchorStyles.Bottom)) == (AnchorStyles.Top | AnchorStyles.Bottom))
                    {
                        size.Height = control.Height;
                    }
                    control.Size = size;
                }
            }
        }
        protected virtual void SetControlLocation(Control control, Point location)
        {
            if (!(control is Form) || !this.PreserveFormLocation)
            {
                if (control.Dock == DockStyle.None)
                {
                    if ((control.Anchor & (AnchorStyles.Left | AnchorStyles.Right)) == AnchorStyles.Right)
                    {
                        location.X = control.Left;
                    }
                    if ((control.Anchor & (AnchorStyles.Top | AnchorStyles.Bottom)) == AnchorStyles.Bottom)
                    {
                        location.Y = control.Top;
                    }
                    control.Location = location;
                }
            }
        }
        protected virtual void ApplyExtenderResource(Dictionary<Type, IExtenderProvider> extenderProviders, Control control, string propertyName, object value)
        {
            IExtenderProvider extenderProvider = null;
            if (propertyName == "ToolTip")
            {
                if (extenderProviders.TryGetValue(typeof(ToolTip), out extenderProvider))
                {
                    (extenderProvider as ToolTip).SetToolTip(control, value as string);
                }
            }
            else
            {
                if (propertyName == "HelpKeyword")
                {
                    if (extenderProviders.TryGetValue(typeof(HelpProvider), out extenderProvider))
                    {
                        (extenderProvider as HelpProvider).SetHelpKeyword(control, value as string);
                    }
                }
                else
                {
                    if (propertyName == "HelpString")
                    {
                        if (extenderProviders.TryGetValue(typeof(HelpProvider), out extenderProvider))
                        {
                            (extenderProvider as HelpProvider).SetHelpString(control, value as string);
                        }
                    }
                    else
                    {
                        if (propertyName == "ShowHelp")
                        {
                            if (extenderProviders.TryGetValue(typeof(HelpProvider), out extenderProvider))
                            {
                                (extenderProvider as HelpProvider).SetShowHelp(control, (bool)value);
                            }
                        }
                        else
                        {
                            if (propertyName == "Error")
                            {
                                if (extenderProviders.TryGetValue(typeof(ErrorProvider), out extenderProvider))
                                {
                                    (extenderProvider as ErrorProvider).SetError(control, value as string);
                                }
                            }
                            else
                            {
                                if (propertyName == "IconAlignment")
                                {
                                    if (extenderProviders.TryGetValue(typeof(ErrorProvider), out extenderProvider))
                                    {
                                        (extenderProvider as ErrorProvider).SetIconAlignment(control, (ErrorIconAlignment)value);
                                    }
                                }
                                else
                                {
                                    if (propertyName == "IconPadding")
                                    {
                                        if (extenderProviders.TryGetValue(typeof(ErrorProvider), out extenderProvider))
                                        {
                                            (extenderProvider as ErrorProvider).SetIconPadding(control, (int)value);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        protected static bool IsVBAssembly(Assembly assembly)
        {
            AssemblyName[] referencedAssemblies = assembly.GetReferencedAssemblies();
            AssemblyName[] array = referencedAssemblies;
            bool result;
            for (int i = 0; i < array.Length; i++)
            {
                AssemblyName assemblyName = array[i];
                if (assemblyName.Name == "Microsoft.VisualBasic")
                {
                    result = true;
                    return result;
                }
            }
            result = false;
            return result;
        }
        protected virtual void ApplyResources(Type componentType, IComponent instance, CultureInfo culture)
        {
            Stream manifestResourceStream = componentType.Assembly.GetManifestResourceStream(componentType.FullName + ".resources");
            if (manifestResourceStream != null)
            {
                Type baseType = componentType.BaseType;
                if (baseType != null)
                {
                    this.ApplyResources(baseType, instance, culture);
                }
                ComponentResourceManager rm = new ComponentResourceManager(componentType);
                SortedList<string, object> sortedList = new SortedList<string, object>();
                this.LoadResources(rm, culture, sortedList);
                Dictionary<string, IComponent> dictionary = new Dictionary<string, IComponent>();
                Dictionary<Type, IExtenderProvider> dictionary2 = new Dictionary<Type, IExtenderProvider>();
                bool flag = CultureManager.IsVBAssembly(componentType.Assembly);
                dictionary["$this"] = instance;
                FieldInfo[] fields = componentType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
                FieldInfo[] array = fields;
                for (int i = 0; i < array.Length; i++)
                {
                    FieldInfo fieldInfo = array[i];
                    string text = fieldInfo.Name;
                    if (flag)
                    {
                        text = text.Substring(1, text.Length - 1);
                    }
                    string text2 = ">>" + text + ".Name";
                    if (sortedList.ContainsKey(text2))
                    {
                        IComponent component = fieldInfo.GetValue(instance) as IComponent;
                        if (component != null)
                        {
                            dictionary[text] = component;
                            this.ApplyResources(component.GetType(), component, culture);
                            if (component is IExtenderProvider)
                            {
                                dictionary2[component.GetType()] = (component as IExtenderProvider);
                            }
                        }
                    }
                }
                foreach (KeyValuePair<string, object> current in sortedList)
                {
                    string text2 = current.Key;
                    object value = current.Value;
                    string[] array2 = text2.Split(new char[]
					{
						'.'
					});
                    string text3 = array2[0];
                    string text4 = array2[1];
                    if (!text3.StartsWith(">>"))
                    {
                        if (!this._excludeProperties.Contains(text4))
                        {
                            IComponent component2 = null;
                            if (dictionary.TryGetValue(text3, out component2))
                            {
                                Control control = component2 as Control;
                                if (control != null)
                                {
                                    string text5 = text4;
                                    if (text5 != null)
                                    {
                                        if (text5 == "Size")
                                        {
                                            this.SetControlSize(control, (Size)value);
                                            continue;
                                        }
                                        if (text5 == "Location")
                                        {
                                            this.SetControlLocation(control, (Point)value);
                                            continue;
                                        }
                                        if (text5 == "ClientSize")
                                        {
                                            if (control is Form && this.PreserveFormSize)
                                            {
                                                continue;
                                            }
                                        }
                                    }
                                }
                                PropertyDescriptor propertyDescriptor = TypeDescriptor.GetProperties(component2).Find(text4, false);
                                if (propertyDescriptor != null && !propertyDescriptor.IsReadOnly && (value == null || propertyDescriptor.PropertyType.IsInstanceOfType(value)))
                                {
                                    propertyDescriptor.SetValue(component2, value);
                                }
                                else
                                {
                                    if (control != null)
                                    {
                                        this.ApplyExtenderResource(dictionary2, control, text4, value);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
